package server

import (
	"context"
	"errors"
	"fmt"
	global2 "longmen/server/config/global"
	_const "longmen/server/pkg/common/helper/const"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql/db_live"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/mysql/models/models_sports"
	"longmen/server/pkg/protobuf"
	"time"
)

func (s *Server) WCGroupMatch(ctx context.Context, r *protobuf.WCGroupMatchReq) (*protobuf.WCGroupMatchResp, error) {
	var (
		wct []*models_main.WCGroupMatch
		res []*protobuf.WCGroupMatch
		err error
	)

	query := global2.Sport().Table("db_world_cup_match")
	if r.GetGroupCode() != "" {
		query.Where("group_code=?", r.GetGroupCode())
	}

	if r.GetMatchDate() != "" {
		query.Where("match_date=?", r.GetMatchDate())
	}

	err = query.Order("group_code").Scan(&wct).Error
	if err != nil {
		return &protobuf.WCGroupMatchResp{
			WorldCupGroupMatch: nil,
		}, nil
	}

	var matchIds []int

	for _, matchTemp := range wct {
		matchIds = append(matchIds, int(matchTemp.MatchID))
	}

	lives, _ := db_live.GetLivePbParamForIds(matchIds)

	var status []*models_sports.MatchTempSchedule
	global2.Sport().Model(&models_sports.MatchTempSchedule{}).Select("match_id, match_status, home_score, away_score").Where("match_id", matchIds).Find(&status)

	for _, v := range wct {
		tempLives := make([]*protobuf.LiveInfo, 0)
		if v.MatchID > 0 {
			for _, l := range lives {
				if int(v.MatchID) == int(l.Matchid) {
					tempLives = append(tempLives, l)
				}
			}

			for _, s := range status {
				if v.MatchID == int64(s.MatchId) {
					v.StatusID = int32(s.MatchStatus)
					v.HomeScores = int32(s.HomeScore)
					v.AwayScores = int32(s.AwayScore)
				}
			}
		}

		res = append(res, &protobuf.WCGroupMatch{
			Lives:        tempLives,
			Id:           v.ID,
			MatchId:      v.MatchID,
			VenueName:    v.VenueName,
			VenueNameEn:  v.VenueNameEn,
			GroupCode:    v.GroupCode,
			HomeTeamId:   v.HomeTeamID,
			HomeTeamName: v.HomeTeamName,
			HomeTeamLogo: v.HomeTeamLogo,
			AwayTeamId:   v.AwayTeamID,
			AwayTeamName: v.AwayTeamName,
			AwayTeamLogo: v.AwayTeamLogo,
			StatusId:     v.StatusID,
			TimePlayed:   v.TimePlayed,
			MatchTime:    v.MatchTime,
			MatchDate:    v.MatchDate,
			HomeScores:   v.HomeScores,
			AwayScores:   v.AwayScores,
			CreatedAt:    v.CreatedAt,
			UpdatedAt:    v.UpdatedAt,
		})
	}
	return &protobuf.WCGroupMatchResp{
		WorldCupGroupMatch: res,
	}, nil
}

func (s *Server) WCTeamPoint(ctx context.Context, r *protobuf.WCTeamPointReq) (*protobuf.WCTeamPointResp, error) {
	var (
		res []*protobuf.WCTeamPoint
		err error
	)

	query := global2.Sport().Table("db_world_cup_point")

	if r.GetGroupCode() != "" {
		query.Where("group_code=?", r.GetGroupCode())
	}

	err = query.Order("score desc").Scan(&res).Error

	if err != nil {
		return &protobuf.WCTeamPointResp{
			WorldCupTeamPoint: nil,
		}, nil
	}

	return &protobuf.WCTeamPointResp{
		WorldCupTeamPoint: res,
	}, nil
}

func (s *Server) WCTeamRank(ctx context.Context, r *protobuf.Empty) (*protobuf.WCTeamRankResp, error) {
	var (
		err error
	)

	var wc_rank []struct {
		RankType int32  `json:"rank_type"`
		Home     string `json:"home"`
		HomeLogo string `json:"home_logo"`
		Away     string `json:"away"`
		AwayLogo string `json:"away_logo"`
	}
	err = global2.Sport().Table("db_world_cup_match_rank").Scan(&wc_rank).Error
	if err != nil {
		return &protobuf.WCTeamRankResp{}, err
	}

	var t16 []*protobuf.WCRankTeam
	var t8 []*protobuf.WCRankTeam
	var t4 []*protobuf.WCRankTeam
	var t2 []*protobuf.WCRankTeam

	for _, v := range wc_rank {
		if v.RankType == 1 {
			t16 = append(t16, &protobuf.WCRankTeam{
				Home: &protobuf.WCTeam{
					Name: v.Home,
					Logo: v.HomeLogo,
				},
				Away: &protobuf.WCTeam{
					Name: v.Away,
					Logo: v.AwayLogo,
				},
			})
		}
		if v.RankType == 2 {
			t8 = append(t8, &protobuf.WCRankTeam{
				Home: &protobuf.WCTeam{
					Name: v.Home,
					Logo: v.HomeLogo,
				},
				Away: &protobuf.WCTeam{
					Name: v.Away,
					Logo: v.AwayLogo,
				},
			})
		}
		if v.RankType == 3 {
			t4 = append(t4, &protobuf.WCRankTeam{
				Home: &protobuf.WCTeam{
					Name: v.Home,
					Logo: v.HomeLogo,
				},
				Away: &protobuf.WCTeam{
					Name: v.Away,
					Logo: v.AwayLogo,
				},
			})
		}
		if v.RankType == 5 {
			t2 = append(t2, &protobuf.WCRankTeam{
				Home: &protobuf.WCTeam{
					Name: v.Home,
					Logo: v.HomeLogo,
				},
				Away: &protobuf.WCTeam{
					Name: v.Away,
					Logo: v.AwayLogo,
				},
			})
		}
	}

	return &protobuf.WCTeamRankResp{
		T16: t16,
		T8:  t8,
		T4:  t4,
		T2:  t2,
	}, nil
}

func (s *Server) WCGameTeam(ctx context.Context, r *protobuf.Empty) (*protobuf.WCGameTeamResp, error) {

	var (
		res []*protobuf.WCGame
		err error
	)

	err = global2.Sport().Table("db_world_cup_game").Order("group_code").Scan(&res).Error

	if err != nil {
		return &protobuf.WCGameTeamResp{
			WorldCupGame: nil,
		}, nil
	}

	return &protobuf.WCGameTeamResp{
		WorldCupGame: res,
	}, nil
}

func (s *Server) WCGameOrder(ctx context.Context, r *protobuf.WCGameOrderReq) (*protobuf.WCGameOrderResp, error) {
	in := r.Diamond * 100 // 克拉倍率 下单额度
	// 检查用户克拉是否足够
	var diamond int
	err := global2.GetR().Model(&models_main.User{}).Where("id=?", r.UserId).Pluck("diamond", &diamond).Error
	if err != nil {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, err
	}
	if r.Diamond < 1 {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("竞猜克拉不得小于1")
	}
	if diamond < int(in) {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("您的可用克拉额度不足")
	}

	// 玩法信息
	var gameTeam = &protobuf.WCGame{}
	err = global2.Sport().Table("db_world_cup_game").Where("id=?", r.Id).Scan(&gameTeam).Error
	if err != nil {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("获取竞猜信息失败")
	}

	if gameTeam.Id <= 0 {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("获取竞猜信息失败")
	}

	if gameTeam.Status != 1 {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("此竞猜玩法已封盘")
	}

	if r.Odds != fmt.Sprintf("%.2f", gameTeam.Odds) {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("赔率已发生变化,请刷新界面后重新参与")
	}

	if r.Diamond < gameTeam.MinBet || r.Diamond > gameTeam.MaxBet {
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, fmt.Errorf("克拉参与额度限制为%d-%d", gameTeam.MinBet, gameTeam.MaxBet)
	}

	rec := &protobuf.WCGameOrder{
		UserId:      r.UserId,
		Diamond:     in,
		OrderId:     util.CreateOrderNo(int(r.UserId), "WC"),
		TeamId:      gameTeam.Id,
		TeamName:    gameTeam.TeamName,
		TeamLogo:    gameTeam.TeamLogo,
		Status:      1,
		CurrentOdds: gameTeam.Odds,
		CreatedAt:   time.Now().Unix(),
		UpdatedAt:   time.Now().Unix(),
	}

	tx := global2.Sport().Begin()

	err = tx.Table("db_world_cup_game_order").Create(&rec).Error
	if err != nil {
		tx.Rollback()
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("下单竞猜失败")
	}

	// 下单扣克拉并记录流水
	profitLog := []*models_main.UserProfit{
		{
			Uid:         int(r.UserId), //获得人的id, 这里是领取人
			CoinCount:   -int(in),      //鹰钻或金坷拉数量
			FUid:        0,             //赠送人的ID, 系统赠送
			ConsumeType: _const.WORLD_CUP_ORDER,
			Type:        _const.TYPE_CONSUME, //赚钱记录
			Content: fmt.Sprintf("%d 世界杯下注竞猜:%d",
				r.UserId,
				r.Diamond,
			),
			Resid:      0,
			Count:      0,
			CreateTime: time.Now(),
			CoinType:   int(_const.CoinDiamond), //1-鹰钻 2-金坷拉
			OrderNo:    util.GenOrderId("RV", 1),
			Liveid:     0,
		},
	}
	userTx := global2.GetX().Begin()
	if err = db_main.InsertUserProfitByTransactions(userTx, profitLog); err != nil {
		tx.Rollback()
		userTx.Rollback()
		global2.Log.Error("%s开通贵族消费记录写入失败:%v", "SubNoble", profitLog)
	}

	// err = cache.PushFundFlow(int(r.SenderUid), -int(r.Diamond), util.CoinDiamond, util.WORLD_CUP_ORDER)
	// if err != nil {
	// 	tx.Rollback()
	// 	userTx.Rollback()
	// 	log.Printf("PushFundFlow Err: %+v", err)
	// }

	_, _, err = db_main.UpdateAmount(int(r.UserId), -int(in), _const.CoinDiamond, _const.WORLD_CUP_ORDER)

	if err != nil {
		tx.Rollback()
		userTx.Rollback()
		return &protobuf.WCGameOrderResp{
			Status: 2,
		}, errors.New("下单竞猜失败")
	}
	tx.Commit()
	userTx.Commit()

	return &protobuf.WCGameOrderResp{
		Status: 1,
	}, nil
}

func (s *Server) WCGameOrderList(ctx context.Context, r *protobuf.WCGameOrderListReq) (*protobuf.WCGameOrderListResp, error) {
	var (
		res    []*protobuf.WCGameOrder
		err    error
		total  int64
		offset int32
		page   int32
		size   int32
	)

	page = r.Page
	if r.Page <= 1 {
		page = 1
	}

	size = r.Size
	if r.Size <= 0 || r.Size >= 20 {
		size = 20
	}
	offset = (page - 1) * size

	err = global2.Sport().Table("db_world_cup_game_order").
		Where("user_id=?", r.UserId).
		Count(&total).
		Offset(int(offset)).
		Limit(int(size)).
		Order("id desc").
		Scan(&res).Error
	if err != nil {
		return &protobuf.WCGameOrderListResp{
			Total: 0,
			List:  nil,
		}, err
	}
	return &protobuf.WCGameOrderListResp{
		Total: total,
		List:  res,
	}, nil
}
